#include "klib.h"

#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)

size_t strlen(const char *s) {
  size_t len=0;
  
  if(s == NULL)
    return 0;

  while(s[len]!='\0'){
    len++;
  }

  return len;
}

char *strcpy(char* dst,const char* src) {
  size_t i = 0;
  if(src == NULL || dst == NULL)
    assert(0);
  
  while(src[i] != '\0'){
    dst[i] = src[i];
    i++;
  }
  return dst;
}

char* strncpy(char* dst, const char* src, size_t n) {
  size_t i;
  if(src == NULL || dst == NULL)
    assert(0);
  for (i = 0; i < n && src[i] != '\0'; i++)
      dst[i] = src[i];
  for ( ; i < n; i++)
      dst[i] = '\0';
  return dst;
}

char* strcat(char* dst, const char* src) {
  size_t dest_len;
  size_t i;
  if(src == NULL || dst == NULL)
    assert(0);

  dest_len = strlen(dst);
  for (i = 0 ; src[i] != '\0' ; i++)
      dst[dest_len + i] = src[i];
  
  dst[dest_len + i] = '\0';
  return dst;
}

int strcmp(const char* s1, const char* s2) {
  
  size_t l1,l2;
  size_t i;

  if(s1 == NULL || s2 == NULL)
    assert(0);
  l1 = strlen(s1);
  l2 = strlen(s2);
  // return l1 == l2;
  for(i=0;i < l1 && i < l2 ; i++){
    if(s1[i] < s2[i])
      return -1;
    else if(s1[i] < s2[i])
      return 1;
  }
  return l1 > l2 ? 1 : 
         l1 < l2 ? -1 : 0;
}

int strncmp(const char* s1, const char* s2, size_t n) {
  size_t l1,l2;
  size_t i;

  if(s1 == NULL || s2 == NULL)
    assert(0);
  
  l1 = strlen(s1);
  l2 = strlen(s2);

  for(i=0;i < l1 && i < l2 && i < n; i++){
    if(s1[i] < s2[i])
      return -1;
    else if(s1[i] < s2[i])
      return 1;
  }
  return i == n ? 0 :
         l1 > l2 ? 1 : 
         l1 < l2 ? -1 : 0;
}

void* memset(void* v,int c,size_t n) {
  
  size_t i;
  uint8_t* bts = (uint8_t* )v;
  if (v == NULL)
    assert(0);
  
  for (i = 0; i < n; i++)
    bts[i] = c;
  
  return v;
}

void* memcpy(void* out, const void* in, size_t n) {
  size_t i;
  uint8_t* src = (uint8_t* )in;
  uint8_t* dest = (uint8_t* )out;

  for (i = 0; i < n; i++)
    dest[i] = src[i];

  return out;
}

int memcmp(const void* s1, const void* s2, size_t n){
  size_t i;
  uint8_t* bt1 = (uint8_t* )s1;
  uint8_t* bt2 = (uint8_t* )s2;  
  if(s1 == NULL || s2 == NULL)
    assert(0);

  for(i=0;i < n; i++){
    if(bt1[i] < bt2[i])
      return -1;
    else if(bt1[i] < bt2[i])
      return 1;
  }
  return 0;
}

#endif
